﻿#ifndef __INC_QG_DX9_CNV_H__
#define __INC_QG_DX9_CNV_H__

#ifdef _MSC_VER
#pragma once
#pragma warning(push)
#pragma warning(disable:4624)
#endif

namespace DX9Convert
{
	// color format
	inline D3DFORMAT DetectColor(const qgColorFormat fmt, bool& alpha)
	{
		switch (fmt)
		{
			case QGCF8_L:
				alpha = false;
				return D3DFMT_L8;

			case QGCF16_L:
				alpha = false;
				return D3DFMT_L16;

			case QGCF32_BGR:
				alpha = false;
				return D3DFMT_X8B8G8R8;

			case QGCF32_BGRA:
				alpha = true;
				return D3DFMT_A8B8G8R8;

			case QGCF16_RGB:
				alpha = false;
				return D3DFMT_R5G6B5;

			case QGCF16_RGBA:
				alpha = true;
				return D3DFMT_A1R5G5B5;

			case QGCF32_RGB:
				alpha = false;
				return D3DFMT_X8R8G8B8;

			case QGCF32_RGBA:
				alpha = true;
				return D3DFMT_A8R8G8B8;

			case QGCF16F_R:
				alpha = false;
				return D3DFMT_R16F;

			case QGCF64F_BGRA:
				alpha = true;
				return D3DFMT_A16B16G16R16F;

			case QGCF32F_R:
				alpha = false;
				return D3DFMT_R32F;

			case QGCF128F_BGRA:
				alpha = true;
				return D3DFMT_A32B32G32R32F;

			case QGCF_DXT1:
				alpha = false;
				return D3DFMT_DXT1;

			case QGCF_DXT2:
				alpha = false;
				return D3DFMT_DXT2;

			case QGCF_DXT3:
				alpha = false;
				return D3DFMT_DXT3;

			case QGCF_DXT4:
				alpha = false;
				return D3DFMT_DXT4;

			case QGCF_DXT5:
				alpha = false;
				return D3DFMT_DXT5;

			default:
				return D3DFMT_UNKNOWN;
		}
	}

	//
	inline qgColorFormat ColorFormat(D3DFORMAT fmt)
	{
		switch (fmt)
		{
			case D3DFMT_L8:
				return QGCF8_L;

			case D3DFMT_L16:
				return QGCF16_L;

			case D3DFMT_A8B8G8R8:
				return QGCF32_BGRA;

			case D3DFMT_A8R8G8B8:
				return QGCF32_RGBA;

			case D3DFMT_X8R8G8B8:
				return QGCF32_RGB;

			case D3DFMT_R16F:
				return QGCF16F_R;

			case D3DFMT_A16B16G16R16F:
				return QGCF64F_BGRA;

			case D3DFMT_R32F:
				return QGCF32F_R;

			case D3DFMT_A32B32G32R32F:
				return QGCF128F_BGRA;

			case D3DFMT_DXT1:
				return QGCF_DXT1;

			case D3DFMT_DXT2:
				return QGCF_DXT2;

			case D3DFMT_DXT3:
				return QGCF_DXT3;

			case D3DFMT_DXT4:
				return QGCF_DXT4;

			case D3DFMT_DXT5:
				return QGCF_DXT5;

			default:
				return QGCF_NONE;
		}
	}

	// 
	inline bool TestCompressedFormat(D3DFORMAT fmt)
	{
		switch (fmt)
		{
			case D3DFMT_DXT1:
			case D3DFMT_DXT2:
			case D3DFMT_DXT3:
			case D3DFMT_DXT4:
			case D3DFMT_DXT5:
				return true;
		}

		return false;
	}

	// 
	inline  D3DPRIMITIVETYPE Topology(qgTopology tpg)
	{
		return (D3DPRIMITIVETYPE)tpg;
	}

	//
	inline D3DCMPFUNC ComparisonOp(qgCmpOp cop)
	{
		return (D3DCMPFUNC)cop;
	}

	//
	inline D3DBLENDOP BlendOp(qgBlendOp op)
	{
		switch (op)
		{
			case QGBLO_FMIN:
				return D3DBLENDOP_MIN;

			case QGBLO_FMAX:
				return D3DBLENDOP_MAX;

			default:
				return (D3DBLENDOP)op;
		}
	}

	//
	inline D3DBLEND BlendValue(qgBlendValue v)
	{
		return (D3DBLEND)v;
	}

	//
	inline void Filter(qgFilter v, D3DTEXTUREFILTERTYPE& mag, D3DTEXTUREFILTERTYPE& min, D3DTEXTUREFILTERTYPE& mip)
	{
		switch (v)
		{
			case QGFLT_MAG_MIN_MIP_POINT:
				mag = D3DTEXF_POINT;
				min = D3DTEXF_POINT;
				mip = D3DTEXF_POINT;
				break;

			case QGFLT_MAG_MIN_POINT_MIP_LINEAR:
				mag = D3DTEXF_POINT;
				min = D3DTEXF_POINT;
				mip = D3DTEXF_LINEAR;
				break;

			case QGFLT_MAG_POINT_MIN_LINEAR_MIP_POINT:
				mag = D3DTEXF_POINT;
				min = D3DTEXF_LINEAR;
				mip = D3DTEXF_POINT;
				break;

			case QGFLT_MAG_POINT_MIN_MIP_LINEAR:
				mag = D3DTEXF_POINT;
				min = D3DTEXF_LINEAR;
				mip = D3DTEXF_LINEAR;
				break;

			case QGFLT_MAG_LINEAR_MIN_MIP_POINT:
				mag = D3DTEXF_LINEAR;
				min = D3DTEXF_POINT;
				mip = D3DTEXF_POINT;
				break;
				
			case QGFLT_MAG_LINEAR_MIN_POINT_MIP_LINEAR:
				mag = D3DTEXF_LINEAR;
				min = D3DTEXF_POINT;
				mip = D3DTEXF_LINEAR;
				break;

			case QGFLT_MAG_MIN_LINEAR_MIP_POINT:
				mag = D3DTEXF_LINEAR;
				min = D3DTEXF_LINEAR;
				mip = D3DTEXF_POINT;
				break;

			case QGFLT_MAG_MIN_MIP_LINEAR:
				mag = D3DTEXF_LINEAR;
				min = D3DTEXF_LINEAR;
				mip = D3DTEXF_LINEAR;
				break;

			case QGFLT_ANISOTROPIC:
				mag = D3DTEXF_ANISOTROPIC;
				min = D3DTEXF_ANISOTROPIC;
				mip = D3DTEXF_ANISOTROPIC;
				break;

			case QGFLTX_POINT:
				mag = D3DTEXF_POINT;
				min = D3DTEXF_POINT;
				mip = D3DTEXF_POINT;
				break;

			case QGFLTX_LINEAR:
				mag = D3DTEXF_LINEAR;
				min = D3DTEXF_LINEAR;
				mip = D3DTEXF_LINEAR;
				break;

			default:
				mag = D3DTEXF_POINT;
				min = D3DTEXF_POINT;
				mip = D3DTEXF_POINT;
				break;
		}
	}

	//
	inline D3DTEXTUREADDRESS Address(qgAddress v)
	{
		return (D3DTEXTUREADDRESS)v;
	}

	//
	inline D3DRESOURCETYPE TexToRtype(qgTextureType type)
	{
		switch (type)
		{
			case QGTEXTURE_1D:
			case QGTEXTURE_2D:
				return D3DRTYPE_TEXTURE;

			case QGTEXTURE_3D:
				return D3DRTYPE_VOLUMETEXTURE;

			case QGTEXTURE_CUBE:
				return D3DRTYPE_CUBETEXTURE;
		}

		return D3DRTYPE_TEXTURE;
	}

	// 
	inline D3DCUBEMAP_FACES CubeMapFace(qgTextureFace face)
	{
		return (D3DCUBEMAP_FACES)(face - 1);
	}

	//
	inline DWORD PrimitiveCount(qgTopology tpg, kint count)
	{
		switch (tpg)
		{
			case QGTPG_POINT_LIST:
				return count;

			case QGTPG_LINE_LIST:
				return count / 2;

			case QGTPG_LINE_STRIP:
				return count - 1;

			case QGTPG_TRI_LIST:
				return count / 3;

			case QGTPG_TRI_STRIP:
				return count - 2;
		}

		return 0;
	}
};

#ifdef _MSC_VER
#pragma warning(pop)
#endif

#endif	// __INC_QG_DX9_CNV_H__
